home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / less-177.lha / less-177 / ifile.c < prev    next >
C/C++ Source or Header  |  1991-03-09  |  4KB  |  193 lines

  1. /*
  2.  * An IFILE represents an input file.
  3.  *
  4.  * It is actually a pointer to an ifile structure,
  5.  * but is opaque outside this module.
  6.  * Ifile structures are kept in a linked list in the order they 
  7.  * appear on the command line.
  8.  * Any new file which does not already appear in the list is
  9.  * inserted after the current file.
  10.  */
  11.  
  12. #include "less.h"
  13.  
  14. struct ifile {
  15.     struct ifile *h_next;        /* Links for command line list */
  16.     struct ifile *h_prev;
  17.     int h_index;            /* Index within command line list */
  18.     char *h_filename;        /* Name of the file */
  19.     struct scrpos h_scrpos;        /* Saved position within the file */
  20. };
  21.  
  22. /*
  23.  * Convert an IFILE (external representation)
  24.  * to a struct file (internal representation), and vice versa.
  25.  */
  26. #define int_ifile(h)    ((struct ifile *)(h))
  27. #define ext_ifile(h)    ((IFILE)(h))
  28.  
  29. /*
  30.  * Anchor for linked list.
  31.  */
  32. static struct ifile anchor = { &anchor, &anchor, 0 };
  33. static int ifiles = 0;
  34.  
  35. /*
  36.  * Allocate a new ifile structure and stick a filename in it.
  37.  * It should go after "prev" in the list
  38.  * (or at the beginning of the list if "prev" is NULL).
  39.  * Return a pointer to the new ifile structure.
  40.  */
  41.     static struct ifile *
  42. new_ifile(filename, prev)
  43.     char *filename;
  44.     struct ifile *prev;
  45. {
  46.     register struct ifile *p;
  47.     register struct ifile *np;
  48.  
  49.     /*
  50.      * Allocate and initialize structure.
  51.      */
  52.     p = (struct ifile *) ecalloc(1, sizeof(struct ifile));
  53.     p->h_filename = filename;
  54.     p->h_scrpos.pos = NULL_POSITION;
  55.  
  56.     /*
  57.      * Link into list.
  58.      */
  59.     if (prev == NULL)
  60.         prev = &anchor;
  61.     p->h_next = prev->h_next;
  62.     p->h_prev = prev;
  63.     prev->h_next->h_prev = p;
  64.     prev->h_next = p;
  65.  
  66.     /*
  67.      * Calculate index for the new one,
  68.      * and adjust the indexes for subsequent ifiles in the list.
  69.      */
  70.     p->h_index = prev->h_index + 1;
  71.     for (np = p->h_next;  np != &anchor;  np = np->h_next)
  72.         np->h_index++;
  73.  
  74.     ifiles++;
  75.     return (p);
  76. }
  77.  
  78. /*
  79.  * Get the ifile after a given one in the list.
  80.  */
  81.     public IFILE
  82. next_ifile(h)
  83.     IFILE h;
  84. {
  85.     register struct ifile *p;
  86.  
  87.     p = (h == NULL_IFILE) ? &anchor : int_ifile(h);
  88.     if (p->h_next == &anchor)
  89.         return (NULL_IFILE);
  90.     return (ext_ifile(p->h_next));
  91. }
  92.  
  93. /*
  94.  * Get the ifile before a given one in the list.
  95.  */
  96.     public IFILE
  97. prev_ifile(h)
  98.     IFILE h;
  99. {
  100.     register struct ifile *p;
  101.  
  102.     p = (h == NULL_IFILE) ? &anchor : int_ifile(h);
  103.     if (p->h_prev == &anchor)
  104.         return (NULL_IFILE);
  105.     return (ext_ifile(p->h_prev));
  106. }
  107.  
  108. /*
  109.  * Return the number of ifiles.
  110.  */
  111.     public int
  112. nifile()
  113. {
  114.     return (ifiles);
  115. }
  116.  
  117. /*
  118.  * Find an ifile structure, given a filename.
  119.  */
  120.     static struct ifile *
  121. find_ifile(filename)
  122.     char *filename;
  123. {
  124.     register struct ifile *p;
  125.  
  126.     for (p = anchor.h_next;  p != &anchor;  p = p->h_next)
  127.         if (strcmp(filename, p->h_filename) == 0)
  128.             return (p);
  129.     return (NULL);
  130. }
  131.  
  132. /*
  133.  * Get the ifile associated with a filename.
  134.  * If the filename has not been seen before,
  135.  * insert the new ifile after "prev" in the list.
  136.  */
  137.     public IFILE
  138. get_ifile(filename, prev)
  139.     char *filename;
  140.     IFILE prev;
  141. {
  142.     register struct ifile *p;
  143.  
  144.     if ((p = find_ifile(filename)) == NULL)
  145.         p = new_ifile(save(filename), int_ifile(prev));
  146.     return (ext_ifile(p));
  147. }
  148.  
  149. /*
  150.  * Get the filename associated with a ifile.
  151.  */
  152.     public char *
  153. get_filename(ifile)
  154.     IFILE ifile;
  155. {
  156.     if (ifile == NULL)
  157.         return (NULL);
  158.     return (int_ifile(ifile)->h_filename);
  159. }
  160.  
  161. /*
  162.  * Get the index of the file associated with a ifile.
  163.  */
  164.     public int
  165. get_index(ifile)
  166.     IFILE ifile;
  167. {
  168.     return (int_ifile(ifile)->h_index); 
  169. }
  170.  
  171. /*
  172.  * Save the file position to be associated with a given file.
  173.  */
  174.     public void
  175. store_pos(ifile, scrpos)
  176.     IFILE ifile;
  177.     struct scrpos *scrpos;
  178. {
  179.     int_ifile(ifile)->h_scrpos = *scrpos;
  180. }
  181.  
  182. /*
  183.  * Recall the file position associated with a file.
  184.  * If no position has been associated with the file, return NULL_POSITION.
  185.  */
  186.     public void
  187. get_pos(ifile, scrpos)
  188.     IFILE ifile;
  189.     struct scrpos *scrpos;
  190. {
  191.     *scrpos = int_ifile(ifile)->h_scrpos;
  192. }
  193.